[ Vue3筆記 ] 封裝打 API + loading狀態


Posted by Akira on 2023-09-05

起因是因為每次在串API的時候,都要重複的寫 isLoading 狀態,雖然有 useFetch 提供有 pending 可以獲取,但總之就是碰到了,看到大神同事把他封裝起來,就來紀錄一下。

專案使用Nuxt3 + Vue3
API封裝使用ofetch(官方推薦) (以下不會提到)

也紀錄一下泛型(Generics) + function的寫法

function useGenerics<T>(params: T[]): T[] {
  return params;
}

T表示Type的縮寫,它可以是任何字。這個function是說傳入的參數是任何東西的數組,回傳也會是跟傳入東西樣的數組。當然你也可以傳入不只一個泛型,比如以下API封裝的函式。

const useMutationApi = <TData, TParams>(
  apiFn: (params: TParams) => Promise<TData>
) => {
...
}

(apiFn: (params: TParams) => Promise) 是函數參數。一個接受 apiFn 參數的函數。

接受類型為 TParams 的 params(泛型參數,用於輸入參數),並返回類型 TData(泛型参数,用於返回類型)的 Promise。apiFn 是你想要進行的 API 調用。這邊沒有給返回的Type是因為typescript會自己推斷,要寫也是可以,就會有點多此一舉。

封裝函示寫在 composables 資料夾裡,這樣在組件或頁面上就可以直接使用。

// composables/useMutationApi.ts
export const useMutationApi = <TData = any, TParams = any>(
  apiFn: (params: TParams) => Promise<TData>
) => {
  const isLoading = ref(false)

  const IS_LOADING = computed(() => isLoading.value)

  const executeApi = async (params: TParams) => {
    isLoading.value = true
    try {
      const result = await apiFn(params)
      return result
    } finally {
      isLoading.value = false
    }
  }

  return {
    executeApi,
    IS_LOADING
  }
}

在組件中的使用方式:

<button :is-loading="userIsLoading" @click="user">User</button>
import {fetchUserData} from '@/api'
const { executeApi: userMutate, IS_LOADING: userIsLoading } = useMutationApi(fetchUserData)

const user = () => {
    userMutate({yourParams})
    }

這樣你在打API的時候就會幫你抓到 loading 狀態,不用每次打 API 都要一個 function 寫一次狀態。


#vue3 #Nuxt3







Related Posts

Command Line 指令 & Vim 心得筆記

Command Line 指令 & Vim 心得筆記

[筆記] 串接 HTTP API 實戰

[筆記] 串接 HTTP API 實戰

淺拷貝與深拷貝

淺拷貝與深拷貝


Comments